﻿using System;
using System.Collections.Generic;
using TPDiseño.Clases_de_Entidad;
using TPDiseño;
using DAO;


namespace TPDiseño.Clases_de_Control
{
    public class Gestor_Evaluacion
    {
        // Depedencia con DAOs
        private DAOEvaluacion miDAOEvaluacion = DAOEvaluacion.Instance;


        public DTO_s.DTOPyEv countEv(TPDiseño.Clases_de_Entidad.Puesto puesto)
        {
            DAO.DAOEvaluacion DAOEvaluacion = new DAO.DAOEvaluacion();
            DTO_s.DTOPyEv DTOpyEv = new DTO_s.DTOPyEv();

            //Utiliza el DAOEvaluacion para contar la cantidad de evaluaciones por 
            //puesto y retorna un entero 
            int cant_ev = DAOEvaluacion.contar(puesto._cod_puesto);
            DTOpyEv._codP = puesto._cod_puesto;
            DTOpyEv._emp = puesto._empresa;
            DTOpyEv._nombre = puesto._nombre;
            DTOpyEv._ev = cant_ev;

            return DTOpyEv;
        }
        public Evaluacion CargarUnaEvaluacion(Cuestionario unCuestionario)
        {
            DAO.DAOEvaluacion daoev = new DAO.DAOEvaluacion();
            return daoev.cargarUno(unCuestionario);
        }
        public void buscar(string cod, string nom ,string emp)
        {
            List<Clases_de_Entidad.Evaluacion> ec = new List<Clases_de_Entidad.Evaluacion>();
            DAO.DAOEvaluacion DAOEvaluacion = new DAO.DAOEvaluacion();
            //el DAOEvaluacion busca las evaluaciones relacionadas al puesto y
            //devuelve List<evaluacion>
            ec = DAOEvaluacion.cargar(cod, emp);
            Interfaces.EmitirOrden2 orden2 = new Interfaces.EmitirOrden2();
            //pasa a emitirOrden2 la coleccion de evaluaciones, el puesto y la empresa
            orden2.ev_coleccion = ec;
            orden2.nom = nom;
            orden2.emp = emp;
            orden2.MdiParent = Interfaces.Principal.ActiveForm;
            orden2.Show();
                  
        }


        public void emitirOrdenMerito(List<Clases_de_Entidad.Evaluacion> ev_selec, string nom, string emp)
        {
            List<List<DTO_s.DTOCuest>> DTOCuest_contenedor = new List<List<DTO_s.DTOCuest>>();
            Gestor_Cuestionario gcu = new Gestor_Cuestionario();
            

            //Por c/ evaluacion seleccionada arma un DTOEvyCuest con la evaluacion y sus DTOCuest
            foreach (Clases_de_Entidad.Evaluacion ev in ev_selec)
            {

                DTOCuest_contenedor.Add(gcu.buscar(ev));
            }

            List<DTO_s.DTOCuest> lista_DTOcuest = new List<DTO_s.DTOCuest>();

            //agrego todos los DTO a una sola lista para poder ordenarlos por puntaje
            foreach (List<DTO_s.DTOCuest> list_DTOcuest in DTOCuest_contenedor)
            {
                foreach (DTO_s.DTOCuest DTOcuest in list_DTOcuest)
                {
                    lista_DTOcuest.Add(DTOcuest);
                }

            }

            //ordena la lista por puntaje mas alto a mas bajo
            lista_DTOcuest.Sort(delegate(DTO_s.DTOCuest d1, DTO_s.DTOCuest d2) { return d1._puntaje.CompareTo(d2._puntaje); });
            lista_DTOcuest.Reverse();
            
            List<generic> lista_generic = new List<generic>();
            
            //cargo los datos a la lista de generic
            foreach (DTO_s.DTOCuest DTOcuest in lista_DTOcuest)
            {
                generic gen = new generic();
                gen._cod_puesto = nom;
                gen._empresa = emp;
                gen._estado = DTOcuest._estado;
                gen._cod_evaluacion = DTOcuest._cod_evaluacion;
                gen._tipo_doc = DTOcuest._candidato._tipo_documento;
                gen._num_doc = DTOcuest._candidato._nro_documento;
                gen._apellido = DTOcuest._candidato._apellido;
                gen._nombre = DTOcuest._candidato._nombre;
                if(DTOcuest._puntaje == -1)
                {
                    gen._puntaje = "";
                }
                else
                {
                    gen._puntaje = DTOcuest._puntaje.ToString();
                }
                gen._fecha_inicio = DTOcuest._fecha_inicio;
                gen._fecha_fin = DTOcuest._fecha_fin;
                gen._ultimo_acceso = DTOcuest._ultimo_acceso;
                gen._cant_accesos = DTOcuest._cant_accesos;

                lista_generic.Add(gen);
              

            }


            Interfaces.reporte rpt = new Interfaces.reporte();
            rpt.Load("reporte.rpt");
            rpt.SetDataSource(lista_generic);
            rpt.SummaryInfo.ReportTitle = "ORDEN DE MÉRITO";
            Interfaces.VistaPrevia vista = new Interfaces.VistaPrevia();
            vista.reporte = rpt;
            vista.MdiParent = Interfaces.Principal.ActiveForm;
            vista.Show();
            

        }

        
        public List<PuestoCompetencia> competenciasAptasParaEvaluar(Puesto unPuesto)
        {
            // Lista nesesaria para recolectar las competencias aptas que se van a evaluar
            List<PuestoCompetencia> competenciasPonderadasParaEvaluar = new List<PuestoCompetencia>();

            // Recorro todas las competencias...
            foreach (PuestoCompetencia competenciasPonderadas in unPuesto._competenciasPonderadas)
            {
                // Lista nesesaria para recolectar los factores aptos para la competencias a evaluar
                List<Factor> factoresParaEvaluar = new List<Factor>();
                
                // Recorro los factores...
                foreach (Factor unFactor in competenciasPonderadas._competencia._factores)
                {
                    // Si el Factor tiene mas de cinco preguntas...
                    if (unFactor._preguntas.Count >= 5){
                        // Factor es apto
                        factoresParaEvaluar.Add(unFactor); // Lo agrego a la lista de factores aptos..
                    }
                 
                }

                // Si hay factores para evaluar  (coleccion no vacia)...
                if (factoresParaEvaluar.Count > 0) {                    
                    // clono o copio la competencia ponderada hasta evaluacion (sin sus factores originales)
                    PuestoCompetencia unaCompetenciaPonderadaParaEvaluar = competenciasPonderadas.clonarHastaEvaluacion();
                    // a la copia le asocio los factores aptos a sus evaluaciones aptas
                    unaCompetenciaPonderadaParaEvaluar._competencia._factores = factoresParaEvaluar;
                    // Finalmente agrego la competencia ponderada a la lista de competencias ponderadas aptas para evaluar
                    competenciasPonderadasParaEvaluar.Add(unaCompetenciaPonderadaParaEvaluar);
                
                }
            }

            return competenciasPonderadasParaEvaluar;

        }

        public List<DTO_s.DTOCandidatoClave> generarClave(List<DTO_s.DTOCandidatoResult> candidatos)
        {
            // Creo una lista para los DTOCandidatoClave
            List<DTO_s.DTOCandidatoClave> candidatosConClave = new List<DTO_s.DTOCandidatoClave>();
                        
            // Recorro cada candidatos (DTOCandidatoResult) a evaluar...
            foreach (DTO_s.DTOCandidatoResult unCandidato in candidatos)
            {
               
                candidatosConClave.Add(new DTO_s.DTOCandidatoClave(unCandidato,                 // El candidato para evaluar
                                                                   generarClave(unCandidato))); // La clave correspondiente al candidato
            }

            // Finalmente retorno los candidatos con sus claves...
            return candidatosConClave;
        }

        public string generarClave(DTO_s.DTOCandidatoResult candidato)
        {
            // Retorno una clave encriptada con MD5 apartir del nombre apellido numero de candidato y tiempo actual
            return Funciones.GetMD5(candidato.nombre + candidato.apellido + candidato.Ncandidato + DateTime.Now.ToString());
        }

        

        //[Probar]
        public Evaluacion evaluar(Puesto unPuestoAevaluar, List<DTO_s.DTOCandidatoClave> candidatosClave, List<PuestoCompetencia> puestosCompetenciasAptosParaEvaluar)
        {
                                 
            // Si hay candidatos listos para evaluarlos y si hay tambien competencias para evaluar....
            if ((candidatosClave.Count > 0) && (puestosCompetenciasAptosParaEvaluar.Count > 0))
            {
                
                //Obtengo la configuracion !!!!!!!!!!! Completar
                DTO_s.DTOTiempoConfiguracion configuracionEvaluacion = Funciones.obtenerConfiguracion();
                    
                //Evaluacion unaEvaluacion = new Evaluacion(0, new DateTime(2012, 3, 9, 16, 5, 7, 123), new DateTime(2013, 3, 9, 16, 5, 7, 123), unPuestoAevaluar);

                Evaluacion unaEvaluacion = new Evaluacion(0, configuracionEvaluacion.Inicio, configuracionEvaluacion.Final, configuracionEvaluacion.Duracion, unPuestoAevaluar);
                

                // Lista de cuestionarios nuevos
                List<Cuestionario> cuestionarios = new List<Cuestionario>();
                
                // --------------------------------------------------------------------------
                Cuestionario nuevoCuestionario;  // Referencia para los nuevos cuestionarios
              

                foreach (DTO_s.DTOCandidatoClave unCandidatoClave in candidatosClave)
                {
                    // Nuevo cuestionario apartir de una evaluacion
                    nuevoCuestionario = new Cuestionario(unaEvaluacion, unCandidatoClave);
                                                          
                    cuestionarios.Add(nuevoCuestionario);

                    // --------------------------------------------------------------------------
                    H_competencia nuevaH_competencia; // Referencia para las nuevas competencias

                    foreach (PuestoCompetencia unaCompetenciaPonderada in puestosCompetenciasAptosParaEvaluar)
                    {

                        // Nueva historial de competencia apartir de una competencia y una ponderacion
                        nuevaH_competencia = new H_competencia(unaCompetenciaPonderada._competencia, unaCompetenciaPonderada._ponderacion);
                        // Se la agrego al cuestionario en proceso
                        nuevoCuestionario._competencias.Add(nuevaH_competencia);

                        H_factor nuevoH_factor;  // Referencia para los nuevos historiales factores

                        // Recorro todos los factores
                        foreach (Factor unFactor in unaCompetenciaPonderada._competencia._factores)
                        {
                           
                            // Creo un nuevo Historial de factor
                            nuevoH_factor = new H_factor(unFactor);
                            // Se lo agrego la lista historial de competencia
                            nuevaH_competencia._factores.Add(nuevoH_factor);

                            H_pregunta nuevaH_pregunta; // Referencia para las nuevas historiales preguntas     


                            List<Pregunta> preguntasAleatoreas = Funciones.obtenerPreguntasAleatriamente(unFactor.preguntas);

                            // Recorro todas las preguntas aleatoreas, 
                            foreach (Pregunta unaPregunta in preguntasAleatoreas) // Por ahora uso la cantidad fija 5.. luego poner en constante
                            {
                                          
                                // Creo un nueva Historial de pregunta
                                nuevaH_pregunta = new H_pregunta(unaPregunta);
                                // Se la agrego al lista historial de preguntas
                                nuevoH_factor._preguntas.Add(nuevaH_pregunta);

                                H_respuesta nuevaH_respuesta;  // Referencia para las nuevas historiales respuestas

                                // Recorro todas las respuestas
                                foreach (Op_Respuesta unaRespuesta in unaPregunta._respuesta._op_respuesta)
                                {
                                                                      
                                    // Creo una nueva historial de respuesta
                                    nuevaH_respuesta = new H_respuesta(unaRespuesta,                                 // Opciones de respuesta
                                                                       unaPregunta._respuesta,                       // Respuestas a estas opciones
                                                                       unaRespuesta.obtenerPonderacion(unaPregunta)  // La ponderecion correspondiente a esa pergunta
                                                                       );

                                    // Se lo agrego a la lista de historiales de respuestas
                                    nuevaH_pregunta._respuestas.Add(nuevaH_respuesta);                                                        

                                }

                           }

                        }

                    }

                }
                //-------------------------------------------------------------------------------------------------------------------------
                // Finalmente retorno la evaluacion completa

                unaEvaluacion._cuestionarios = cuestionarios;
                
                return unaEvaluacion;

            }
            else
            {   //-------------------------------------------------------------------------------------------------------------------------
                //                             -----  No hay evluacion dado que no hay candidatos y/o competencias -----  
                // Hay que hacerlo con excepciones !!!!!!!!!!!
                return new Evaluacion();
            }
                        
        }

       
        
        public void guardar(Evaluacion unaEvaluacion)
        {
           // Guardo la evaluacion
           miDAOEvaluacion.guardar(unaEvaluacion);
            
        }
    }
}
